﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using PlasmaMes.A_Models;
using PlasmaMes.Services;
using Serilog;
using Sunny.UI;

namespace PlasmaMes
{
    public partial class Form_Auto: Form
    {
        private System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
         
        public static volatile bool istest = false;

        public static volatile bool isdowntest = false;

        public int v = 0;
             
        public Form_Auto()
        {
            InitializeComponent();
            LogService.UpdateRichTextBoxEvent += Log_UpdateRichTextBoxEvent;
        }

        private void Form_Auto_Load(object sender, EventArgs e)
        {
            timer.Interval = 100;
            timer.Tick += Timer_Tick;

            //int.TryParse("00001\r", out v);
            //MessageBox.Show($"{v}");

            //if(v == 1) MessageBox.Show($"{v + 100}");




            if (File.Exists(RunParam.Instance.RunParamPath))
            {
                var rp = JsonHelper.JsonFileToObj<RunParam>(RunParam.Instance.RunParamPath);

                RunParam.Instance.Keyence_IP = rp.Keyence_IP;
                RunParam.Instance.Keyence_Port = rp.Keyence_Port;

                RunParam.Instance.PLC_IP = rp.PLC_IP;
                RunParam.Instance.Keyence_Down_IP = rp.Keyence_Down_IP;
                RunParam.Instance.Keyence_Down_Port = rp.Keyence_Down_Port;

                RunParam.Instance.Addr_XJPLC_ProductCompleted = rp.Addr_XJPLC_ProductCompleted;
                RunParam.Instance.Addr_XJPLC_Feeding = rp.Addr_XJPLC_Feeding;
                RunParam.Instance.Addr_XJPLC_HadFed = rp.Addr_XJPLC_HadFed;

                RunParam.Instance.Addr_KYPLC_SendSignal = rp.Addr_KYPLC_SendSignal;
                RunParam.Instance.Addr_KYPLC_RecvRfid = rp.Addr_KYPLC_RecvRfid;
                RunParam.Instance.Addr_KYPLC_Feeding = rp.Addr_KYPLC_Feeding;
                RunParam.Instance.Addr_KYPLC_HadFed = rp.Addr_KYPLC_HadFed ;

                RunParam.Instance.Addr_KYPLC_Down_RecvReturn = rp.Addr_KYPLC_Down_RecvReturn;
                RunParam.Instance.Addr_KYPLC_Down_SendNeed = rp.Addr_KYPLC_Down_SendNeed;
                RunParam.Instance.Addr_XJPLC_RecvNeed = rp.Addr_XJPLC_RecvNeed;
                RunParam.Instance.Addr__XJPLC_SendReturn = rp.Addr__XJPLC_SendReturn;



                tb_ky_ip.Text = RunParam.Instance.Keyence_IP;
                tb_ky_port.Text = RunParam.Instance.Keyence_Port.ToString();
                tb_下游基恩士IP.Text = RunParam.Instance.Keyence_Down_IP;
                tb_下游基恩士端口.Text = RunParam.Instance.Keyence_Down_Port.ToString() ;

                tb_本机台产品到位地址.Text = RunParam.Instance.Addr_XJPLC_ProductCompleted;
                tb_本机台收动上料中地址.Text = RunParam.Instance.Addr_XJPLC_Feeding;
                tb_本机台收动上料完成地址.Text = RunParam.Instance.Addr_XJPLC_HadFed;

                tb_上游机台发送信号地址.Text = RunParam.Instance.Addr_KYPLC_SendSignal;
                //tb_上游机台收到RFID地址.Text = RunParam.Instance.Addr_KYPLC_RecvRfid;
                tb_上游机台上料中地址.Text = RunParam.Instance.Addr_KYPLC_Feeding;
                tb_上游机台上料完成地址.Text = RunParam.Instance.Addr_KYPLC_HadFed;



                tb_下游机台收到回流信号地址.Text = RunParam.Instance.Addr_KYPLC_Down_RecvReturn; 
                tb_下游发出要料信号地址.Text =  RunParam.Instance.Addr_KYPLC_Down_SendNeed;  
                tb_本机台收到下料要料信号地址.Text = RunParam.Instance.Addr_XJPLC_RecvNeed;      
                tb_本机台发出回流信号地址.Text = RunParam.Instance.Addr__XJPLC_SendReturn;    
            }

        }


        //private void Test()
        //{
           
           


        //}

        private void Timer_Tick(object sender, EventArgs e)
        {
            int value = 0;
            if(Modbus.Instance.ReadRegister_Int16("5000", ref value))
            {
                if(value == 1)
                {
                    //上报进站
                }

            }
            else
            {

            }


            if (Modbus.Instance.ReadRegister_Int16("5001", ref value))
            {
                if (value == 0)
                {
                    //上报出站
                }

            }
            else
            {

            }



            if (Modbus.Instance.ReadRegister_Int16("6000", ref value))
            {
                if (value == 1)
                {
                    //向上游发出允许放料信号
                }

            }
            else
            {

            }



            if (Modbus.Instance.ReadRegister_Int16("6001", ref value))
            {
                if (value == 1)
                {
                    //向上游发出清料信号
                }

            }
            else
            {

            }



            if (Modbus.Instance.ReadRegister_Int16("6002", ref value))
            {
                if (value == 1)
                {
                    //向上游发出机台运行信号
                }

            }
            else
            {

            }

            if (Modbus.Instance.ReadRegister_Int16("6003", ref value))
            {
                if (value == 1)
                {
                    //向上游写入RFID信息
                }

            }
            else
            {

            }


        }



        private void Log_UpdateRichTextBoxEvent(string msg, Log_Type log_Type)
        {
            Color color;

            if (log_Type == Log_Type.Info)
            {
                color = Color.Green;
                Log.Information(msg);
            }
            else if (log_Type == Log_Type.Warning)
            {
                color = Color.Orange;
                Log.Warning(msg);
            }
            else
            {
                color = Color.Red;
                Log.Error(msg);
                //Form_Main.ErrorLogger.Error(msg);
                //SendErrorMsgEvent?.Invoke(msg);
            }


            this.BeginInvoke((MethodInvoker)delegate
            {
                if (rtb_log.Lines.Length > 1000)
                {
                    rtb_log.SelectionStart = 0;
                    rtb_log.SelectionLength = rtb_log.GetFirstCharIndexFromLine(1);
                    rtb_log.SelectedText = " ";
                }

                // 更新日志
                //rtb_log.SelectionStart = rtb_log.TextLength;
                // rtb_log.SelectionLength = 0;
                rtb_log.SelectionColor = color;

                if (rtb_log.Lines.Length != 0)
                    rtb_log.AppendText($"\n{DateTime.Now} [{log_Type}] {msg}");
                else
                    rtb_log.AppendText($"{DateTime.Now} [{log_Type}] {msg}");

                // 滚动到最新行
                //rtb_log.SelectionColor = rtb_log.ForeColor;
                // rtb_log.SelectionStart = rtb_log.Text.Length;
                rtb_log.ScrollToCaret();
            });
        }

        private void uiButton_连接_Click(object sender, EventArgs e)
        {
            if(string.IsNullOrEmpty(tb_ky_ip.Text))
            {
                MessageBox.Show("上游机台IP地址不能为空");
                return;
            }

            if(string.IsNullOrEmpty(tb_ky_port.Text))
            {
                MessageBox.Show("上游机台端口号不能为空");
                return;
            }

            if(TcpService.Instance.Tcp_Connected(tb_ky_ip.Text, int.Parse(tb_ky_port.Text)))
            {
                LogService.Instance.LogInfo("上游基恩士PLC连接成功");
            }
            else
            {
                LogService.Instance.LogError("上游基恩士PLC连接失败");
            }
           
        }

        private void uiButton_断开_Click(object sender, EventArgs e)
        {
            if(TcpService.Instance.Tcp_DisConnected())
            {
                LogService.Instance.LogInfo("基恩士PLC断开连接成功");
            }
            else
            {
                LogService.Instance.LogError("基恩士PLC断开连接失败");
            }
        }


        private void bt_开始测试_Click(object sender, EventArgs e)
        {
            bt_开始测试.Enabled = false;

            Task.Run(async () => {

                if (TcpService.Instance.istcpConnected == false)
                {
                    LogService.Instance.LogError("与上游机台还没建立连接，请先连接");
                    bt_开始测试.Enabled = true;
                    return;
                }

                if (Modbus.Instance.isModbusConnect == false)
                {
                    LogService.Instance.LogError("与本机还没建立连接，请先连接");
                    bt_开始测试.Enabled = true;
                    return;
                }

                if(string.IsNullOrEmpty(tb_本机台产品到位地址.Text))
                {
                    LogService.Instance.LogError("本机台产品到位地址不能为空");
                    bt_开始测试.Enabled = true;
                    return;
                }

                if (string.IsNullOrEmpty(tb_本机台收动上料中地址.Text))
                {
                    LogService.Instance.LogError("本机台收动上料中地址不能为空");
                    bt_开始测试.Enabled = true;
                    return;
                }

                if (string.IsNullOrEmpty(tb_本机台收动上料完成地址.Text))
                {
                    LogService.Instance.LogError("本机台收动上料完成地址不能为空");
                    bt_开始测试.Enabled = true;
                    return;
                }

                if (string.IsNullOrEmpty(tb_本机台产品到位地址.Text))
                {
                    LogService.Instance.LogError("本机台产品到位地址不能为空");
                    bt_开始测试.Enabled = true;
                    return;
                }

                if (string.IsNullOrEmpty(tb_上游机台发送信号地址.Text))
                {
                    LogService.Instance.LogError("上游机台发送信号地址不能为空");
                    bt_开始测试.Enabled = true;
                    return;
                }


                if (string.IsNullOrEmpty(tb_上游机台上料中地址.Text))
                {
                    LogService.Instance.LogError("上游机台上料中地址不能为空");
                    bt_开始测试.Enabled = true;
                    return;
                }

                if (string.IsNullOrEmpty(tb_上游机台上料完成地址.Text))
                {
                    LogService.Instance.LogError("上游机台上料完成地址不能为空");
                    bt_开始测试.Enabled = true;
                    return;
                }


                int value = 0;
                string msg = string.Empty;
                string result = string.Empty;
                istest = true;
                while (istest)
                {
                    if(Modbus.Instance.ReadRegister_Int16(tb_本机台产品到位地址.Text, ref value))
                    {
                       
                        msg = "WR" + " " + $"{tb_上游机台发送信号地址.Text}" + " " + value.ToString() + "\r";

                        await TcpService.Instance.Tcp_SemdMsg(msg);

                        //LogService.Instance.LogInfo("已向上游机台发送产品到位信号");
                            
                    }

                    msg = "RD" + " " + $"{tb_上游机台上料中地址.Text}" + "\r";

                    result = await TcpService.Instance.ReadFormPLC(msg);
                    if(int.TryParse(result, out value))
                    {
                        //LogService.Instance.LogInfo("已读取到上游机台在上料中信号");
                        Modbus.Instance.WriteOneRegister_Short(tb_本机台收动上料中地址.Text, (short)value, false);
                    }

                    msg = "RD" + " " + $"{tb_上游机台上料完成地址.Text}" + "\r";
                    result = await TcpService.Instance.ReadFormPLC(msg);
                    if (int.TryParse(result, out value))
                    {
                        //LogService.Instance.LogInfo("已读取到上游机台上料完成信号");
                        Modbus.Instance.WriteOneRegister_Short(tb_本机台收动上料完成地址.Text, (short)value, false);
                    }
                    
                        
                    Thread.Sleep(1000);
                }

                this.BeginInvoke((MethodInvoker)delegate { bt_开始测试.Enabled = true; });

                LogService.Instance.LogInfo("测试任务结束");

                istest = false;
             
            });


        }

        private void bt_测试停止_Click(object sender, EventArgs e)
        {
            istest = false;
            bt_开始测试.Enabled = true;
        }

        private void bt_保存参数_Click(object sender, EventArgs e)
        {
            RunParam.Instance.Keyence_IP = tb_ky_ip.Text;
            RunParam.Instance.Keyence_Port = int.Parse(tb_ky_port.Text);

            RunParam.Instance.Addr_XJPLC_ProductCompleted = tb_本机台产品到位地址.Text;
            RunParam.Instance.Addr_XJPLC_Feeding = tb_本机台收动上料中地址.Text;
            RunParam.Instance.Addr_XJPLC_HadFed = tb_本机台收动上料完成地址.Text;

            RunParam.Instance.Addr_KYPLC_SendSignal = tb_上游机台发送信号地址.Text;
            //RunParam.Instance.Addr_KYPLC_RecvRfid = tb_上游机台收到RFID地址.Text;
            RunParam.Instance.Addr_KYPLC_Feeding = tb_上游机台上料中地址.Text ;
            RunParam.Instance.Addr_KYPLC_HadFed = tb_上游机台上料完成地址.Text;;

            RunParam.Instance.Addr_KYPLC_Down_RecvReturn = tb_下游机台收到回流信号地址.Text;
            RunParam.Instance.Addr_KYPLC_Down_SendNeed = tb_下游发出要料信号地址.Text;
            RunParam.Instance.Addr_XJPLC_RecvNeed = tb_本机台收到下料要料信号地址.Text;
            RunParam.Instance.Addr__XJPLC_SendReturn = tb_本机台发出回流信号地址.Text;
            RunParam.Instance.Keyence_Down_IP = tb_下游基恩士IP.Text;
            RunParam.Instance.Keyence_Down_Port = int.Parse(tb_下游基恩士端口.Text);


            LogService.Instance.LogInfo("保存参数成功");

            JsonHelper.ObjToJsonFile(RunParam.Instance, RunParam.Instance.RunParamPath);
        }

        private void bt_下游基恩士连接_Click(object sender, EventArgs e)
        {
            if(string.IsNullOrEmpty(tb_下游基恩士IP.Text))
            {
                MessageBox.Show("下游机台IP不能为空");
                return;
            }

            if(string.IsNullOrEmpty(tb_下游基恩士端口.Text))
            {
                MessageBox.Show("下游机台端口不能为空");
                return;
            }

            if(TcpService.Instance.D_Tcp_Connected(tb_下游基恩士IP.Text, int.Parse(tb_下游基恩士端口.Text)))
            {
                LogService.Instance.LogInfo("下游基恩士PLC连接成功");
            }
            else
            {
                LogService.Instance.LogError("下游基恩士PLC连接失败");
            }
        }

        private void bt_下游开始测试_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(tb_本机台收到下料要料信号地址.Text))
            {
                LogService.Instance.LogError("本机台收到下料要料信号地址不能为空");
                return;
            }
            if (string.IsNullOrEmpty(tb_本机台发出回流信号地址.Text))
            {
                LogService.Instance.LogError("本机台发出回流信号地址不能为空");
                return;
            }
            if (string.IsNullOrEmpty(tb_下游发出要料信号地址.Text))
            {
                LogService.Instance.LogError("下游发出要料信号地址不能为空");
                return;
            }
            if (string.IsNullOrEmpty(tb_下游机台收到回流信号地址.Text))
            {
                LogService.Instance.LogError("下游机台收到回流信号地址不能为空");
                return;
            }


            if(!Modbus.Instance.isModbusConnect)
            {
                LogService.Instance.LogError("还没与本机台PLC建立连接");
                return;
            }

            if(!TcpService.Instance.d_istcpConnected)
            {
                LogService.Instance.LogError("还没与下游机台PLC建立连接");
                return;
            }
                



            bt_下游开始测试.Enabled = false;

            int value = 0;
            string readmsg = "RD" + " " + $"{tb_下游发出要料信号地址.Text}" + "\r";
            //string writemsg = "WR" + " " + $"{tb_下游机台收到回流信号地址.Text}" + " " + "1" + "\r";
            string writemsg = string.Empty;
            string result = string.Empty;
            isdowntest = true;

            Task.Run(async () => {

                while (isdowntest)
                {
                    
                    result = await TcpService.Instance.D_ReadFormPLC(readmsg);
                    if (int.TryParse(result, out value))
                    {
                        if(value == 1)
                        {
                            LogService.Instance.LogInfo("收到下料机台要料信号");
                        }

                        if(Modbus.Instance.WriteOneRegister_Short(tb_本机台收到下料要料信号地址.Text, (short)value, false))
                        {
                           
                        }
                        else
                        {
                            LogService.Instance.LogError("将下游机台下料要料信号地址值 写入本机台PLC寄存器失败");
                        }
                    }

                    if(Modbus.Instance.ReadRegister_Int16(tb_本机台发出回流信号地址.Text, ref value))
                    {
                        writemsg = "WR" + " " + $"{tb_下游机台收到回流信号地址.Text}" + " " + value.ToString() + "\r";
                        await TcpService.Instance.D_Tcp_SemdMsg(writemsg);
                    }
                    else
                    {

                    }

                    Thread.Sleep(1000);
                }

                LogService.Instance.LogInfo("退出下料测试任务");



            });
        }

        private void bt_下游测试停止_Click(object sender, EventArgs e)
        {
            isdowntest = false;

            bt_下游开始测试.Enabled = true;


        }
    }
}
